package com.example.demo.config;

import cn.hutool.core.date.LocalDateTimeUtil;
import com.google.common.collect.Lists;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;

/**
 * @author hulei
 * @version 1.0
 * @date 2022-01-07 10:30
 * @target
 */
public class MonthShardingAlgorithm implements PreciseShardingAlgorithm<String>, RangeShardingAlgorithm<String> {

    @Override
    public String doSharding(Collection<String> collection, PreciseShardingValue<String> preciseShardingValue) {

        String dataTimeStr = preciseShardingValue.getValue();
        LocalDateTime dateTime =   LocalDateTimeUtil.parse(dataTimeStr, "yyyy-MM-dd HH:mm:ss");
        int month = dateTime.getMonthValue();
        for (String tableName : collection) {
            if (tableName.endsWith(String.valueOf(month))) {
                return tableName;
            }
        }
        throw new UnsupportedOperationException(
                String.format("MonthShardingAlgorithm not support,logicTableName:%s,month:%s,tableList:%s ",
                        preciseShardingValue.getLogicTableName(),
                        month,
                        collection));
    }

    @Override
    public Collection<String> doSharding(Collection<String> tableNames, RangeShardingValue<String> rangeShardingValue) {

        LinkedHashSet<String> result = new LinkedHashSet<>();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // between and 的起始值
        if (true){
            return tableNames;
        }

        LocalDateTime lower = LocalDateTime.parse(rangeShardingValue.getValueRange().lowerEndpoint(),formatter);
        LocalDateTime upper = LocalDateTime.parse(rangeShardingValue.getValueRange().upperEndpoint(),formatter);

        List<String> timeList = packDateStrListByInterval(lower.toLocalDate(),upper.toLocalDate());
        // 循环范围计算分表逻辑
        for(String time : timeList){
            for(String tableName : tableNames){
                if(tableName.endsWith(time)){
                    result.add(tableName);
                }
            }
        }
        return result;
    }

    //与Demo的业务相关，不需要具体看清该业务逻辑，只要知道doSharding方法时用于筛选除需要进行查询的所有表即可
    private List<String> packDateStrListByInterval(LocalDate startDate, LocalDate endDate) {
        List<String> list = Lists.newArrayList();
        if (endDate.isBefore(startDate)) {
            return list;
        }
        LocalDate tmp = startDate;
        list.add(String.valueOf(tmp.getMonthValue()));
        while (true) {
            tmp = tmp.plusMonths(1);
            if (endDate.isBefore(tmp)) {
                break;
            }
            list.add(String.valueOf(tmp.getMonthValue()));
        }

        return list;
    }

}
